package com.nuanshui.framework.security;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.Key;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class AESUtil {
	
	
	 /**   
     * 密钥算法   
     * java6支持56位密钥，bouncycastle支持64位   
     * */   
    public static final String KEY_ALGORITHM = "AES";    
         
    /**   
     * 加密/解密算法/工作模式/填充方式   
     *    
     * JAVA6 支持PKCS5PADDING填充方式   
     * Bouncy castle支持PKCS7Padding填充方式   
     * */   
    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    
    public static byte[] initkey = null;
         
    /**   
     *    
     * 生成密钥，java6只支持56位密钥，bouncycastle支持64位密钥  
     * 这里的密钥写死
     * @return byte[] 二进制密钥   
     * */   
    public static byte[] initkey(){ 
    	if(initkey == null){
    		synchronized (AESUtil.class) {
    			if(initkey == null){
    				initkey = new byte[] { 0x08, 0x08, 0x04, 0x0b, 0x02, 0x0f, 0x0b, 0x0c,  
    	                    0x01, 0x03, 0x09, 0x07, 0x0c, 0x03, 0x07, 0x0a}; 
    			}
			}
    	}
        return initkey;
    }  

    /**   
     * 转换密钥   
     * @param key 二进制密钥   
     * @return Key 密钥   
     * */   
    public static Key toKey(byte[] key){  
		try{
			 //实例化DES密钥    
			//生成密钥 
		    SecretKey secretKey = new SecretKeySpec(key,KEY_ALGORITHM);    
		    return secretKey; 
    	}catch(Exception e){
    		e.printStackTrace();
    	}
		
		return null;
          
    }    
         
    /**   
     * 加密数据   
     * @param data 待加密数据   
     * @param key 密钥   
     * @return byte[] 加密后的数据   
     * */   
    public static byte[] encrypt(byte[] data,byte[] key){  
		try{
			 //还原密钥    
		    Key k = toKey(key);
		    /**   
		     * 实例化   
		     * 使用 PKCS7PADDING 填充方式，按如下方式实现,就是调用bouncycastle组件实现   
		     * Cipher.getInstance(CIPHER_ALGORITHM,"BC")   
		     */   
		    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());  
		    Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");    
		    //初始化，设置为加密模式    
		    cipher.init(Cipher.ENCRYPT_MODE, k);    
		    //执行操作    
		    return cipher.doFinal(data); 
    	}catch(Exception e){
    		e.printStackTrace();
    	}
		return null;
    } 
    
    /**
     *  加密数据   , 使用默认的密钥
     * @author Gonzo
     * @date 2017年3月21日下午7:31:58
     * @param data
     * @return
     */
    public static byte[] encrypt(byte[] data){
    	return encrypt(data, initkey());
    }
    
    /**   
     * 解密数据   
     * @param data 待解密数据   
     * @param key 密钥   
     * @return byte[] 解密后的数据   
     * */   
    public static byte[] decrypt(byte[] data,byte[] key){    
		try{
			Key k = toKey(key);    
		    Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);    
		    //初始化，设置为解密模式  
		    cipher.init(Cipher.DECRYPT_MODE, k);    
		    //执行操作    
		    return cipher.doFinal(data); 
    	}catch(Exception e){
    		e.printStackTrace();
    	}
		return null;
           
    }   
    
    /**
     * 前段传过来的16进制的32位字符串,转成16个byte
     * @author Gonzo
     * @date 2017年3月21日下午8:59:46
     * @param str
     * @return
     */
    public static byte[] sixteenStrToByte(String str){
    	try{
    		byte[] resultByte = new byte[16];
        	
            for(int i=0, z=0; i<32; i+=2, z++){
            	int sixten = new BigInteger(str.substring(i, i+2), 16).intValue();
            	resultByte[z] = (byte) sixten;
            }
            return resultByte;
    	}catch(Exception e){
    		e.printStackTrace();
    	}
    	
    	return null;
    }
    
    /**   
     * 解密数据  , 使用默认的密钥
     * @param data 待解密数据   
     * @return byte[] 解密后的数据   
     * */ 
    public static byte[] decrypt(byte[] data){
    	return decrypt(data, initkey());    
    }
    /**   
     * @param args   
     * @throws UnsupportedEncodingException   
     * @throws Exception    
     */   
    public static void main(String[] args){    
           
        String str="654321";    
        System.out.println("原文："+str);    

        //初始化密钥    
        byte[] key;  
        try {  
            key = AESUtil.initkey();
            System.out.print("密钥：");    
            for(int i = 0;i<key.length;i++){  
                System.out.printf("%x", key[i]);  
            }  
            System.out.print("\n");  
            //加密数据    
            byte[] data = AESUtil.encrypt(str.getBytes(), key);    
            System.out.print("加密后：");   
            for(int i = 0;i<data.length;i++){  
                System.out.printf("%x", data[i]);  
            }  
            String str1 = "41643c2d981e8d7241f59c749115ef64";
            char[] charArray = str1.toCharArray();
            
            
            /*for(int i=0; i<charArray.length; i++){
            	b1[i] = (byte) charArray[i];
            }*/
            String dataStr = new String(data);
            data = dataStr.getBytes("UTF-8");
            
            System.out.print("\n");  
            //解密数据    
            data = AESUtil.decrypt(data, key);    
            System.out.println("解密后："+new String(data));   
        } catch (Exception e) {  
            e.printStackTrace();  
        }    
            
    }
}
